package org.gdstash.file;

import org.gdstash.util.GDConstants;
import org.gdstash.util.GDMsgLogger;
import org.ini4j.Ini;

import java.awt.*;
import java.io.File;
import java.io.IOException;

public class IniConfig implements Cloneable {
    public static final String DEFAULT_LANGUAGE = "English";
    public static final int AFFIX_COMBI_VALID = 1;
    public static final int AFFIX_COMBI_ALL_COMBOS = 2;
    public static final int AFFIX_COMBI_ALL_AFFIXES = 3;
    private static String iniPath;
    static {
        IniConfig.iniPath = GDConstants.USER_HOME + GDConstants.FILE_SEPARATOR + "GDStash" + GDConstants.FILE_SEPARATOR + "GDStash.ini";
    }

    private File iniFile;
    public DirectorySection sectDir;
    public RestrictionSection sectRestrict;
    public UISection sectUI;
    public HistorySection sectHistory;
    public WindowSection sectWindow;
    private DirectorySection sectDirLoaded;
    private RestrictionSection sectRestrictLoaded;
    private UISection sectUILoaded;
    private HistorySection sectHistoryLoaded;
    private WindowSection sectWindowLoaded;

    public IniConfig() {
        this.sectDir = new DirectorySection();
        this.sectRestrict = new RestrictionSection();
        this.sectUI = new UISection();
        this.sectHistory = new HistorySection();
        this.sectWindow = new WindowSection();
        this.sectDirLoaded = new DirectorySection();
        this.sectRestrictLoaded = new RestrictionSection();
        this.sectUILoaded = new UISection();
        this.sectHistoryLoaded = new HistorySection();
        this.sectWindowLoaded = new WindowSection();
    }

    public IniConfig(final File file) {
        this();
        this.iniFile = file;
        try {
            if (!file.exists()) {
                final File dir = file.getParentFile();
                if (dir != null && !dir.exists()) {
                    dir.mkdirs();
                }
                file.createNewFile();
            }
            this.ini = new Ini(file);
        } catch (IOException ex) {
            this.ini = null;
        }
    }

    public Object clone() {
        final IniConfig config = new IniConfig();
        config.sectDirLoaded = this.sectDirLoaded.clone();
        config.sectRestrictLoaded = this.sectRestrictLoaded.clone();
        config.sectUILoaded = this.sectUILoaded.clone();
        config.sectHistoryLoaded = this.sectHistoryLoaded.clone();
        config.sectWindowLoaded = this.sectWindowLoaded.clone();
        config.sectDir = this.sectDir.clone();
        config.sectRestrict = this.sectRestrict.clone();
        config.sectUI = this.sectUI.clone();
        config.sectHistory = this.sectHistory.clone();
        config.sectWindow = this.sectWindow.clone();
        config.iniFile = this.iniFile;
        return config;
    }
    private Ini ini;

    public boolean read() {
        boolean success = false;
        try {
            (this.ini = new Ini(this.iniFile)).load();
            this.sectDirLoaded.getIniValues(this.ini);
            this.sectRestrictLoaded.getIniValues(this.ini);
            this.sectUILoaded.getIniValues(this.ini);
            this.sectHistoryLoaded.getIniValues(this.ini);
            this.sectWindowLoaded.getIniValues(this.ini);
            this.sectDir = this.sectDirLoaded.clone();
            this.sectRestrict = this.sectRestrictLoaded.clone();
            this.sectUI = this.sectUILoaded.clone();
            this.sectHistory = this.sectHistoryLoaded.clone();
            this.sectWindow = this.sectWindowLoaded.clone();
            success = true;
        } catch (IOException ex) {
            success = false;
        }
        return success;
    }

    public boolean write() {
        boolean success = false;
        this.sectDir.putIniValues(this.ini);
        this.sectRestrict.putIniValues(this.ini);
        this.sectUI.putIniValues(this.ini);
        this.sectHistory.putIniValues(this.ini);
        this.sectWindow.putIniValues(this.ini);
        try {
            this.ini.store();
            this.sectDirLoaded = this.sectDir.clone();
            this.sectRestrictLoaded = this.sectRestrict.clone();
            this.sectUILoaded = this.sectUI.clone();
            this.sectHistoryLoaded = this.sectHistory.clone();
            this.sectWindowLoaded = this.sectWindow.clone();
            success = true;
        } catch (IOException ex) {
            GDMsgLogger.addError(ex);
            success = false;
        }
        return success;
    }

    public boolean writeWindowSection() {
        boolean success = false;
        this.sectDirLoaded.putIniValues(this.ini);
        this.sectRestrictLoaded.putIniValues(this.ini);
        this.sectUILoaded.putIniValues(this.ini);
        this.sectHistory.putIniValues(this.ini);
        this.sectWindow.putIniValues(this.ini);
        try {
            this.ini.store();
            success = true;
        } catch (IOException ex) {
            GDMsgLogger.addError(ex);
            success = false;
        }
        return success;
    }

    public static IniConfig get() {
        final File file = new File(IniConfig.iniPath);
        IniConfig config = new IniConfig(file);
        if (!config.read()) {
            config = new IniConfig(file);
        }
        return config;
    }

    public static class DirectorySection implements Cloneable {
        private static final String SECTION = "directories";
        private static final String KEY_GD_PATH = "gd_path";
        private static final String KEY_SAVE_PATH = "save_path";
        private static final String KEY_EXPORT_PATH = "export_path";
        private static final String KEY_BUFFER_TYPE = "buffer_type";
        public String gdPath;
        public String savePath;
        public String exportPath;

        public DirectorySection() {
            final File file = null;
            this.gdPath = "";
            this.savePath = "";
            this.exportPath = GDConstants.USER_DIR;
        }

        public DirectorySection clone() {
            final DirectorySection section = new DirectorySection();
            section.gdPath = this.gdPath;
            section.savePath = this.savePath;
            section.exportPath = this.exportPath;
            return section;
        }

        public void getIniValues(final Ini ini) {
            File file = null;
            String dirSteam = null;
            this.gdPath = ini.get((Object) "directories", (Object) "gd_path");
            if (this.gdPath == null) {
                this.gdPath = "C:\\Program Files (x86)\\Steam\\steamapps\\common\\Grim Dawn";
                file = new File(this.gdPath);
                if (file.exists()) {
                    dirSteam = "C:\\Program Files (x86)\\Steam";
                } else {
                    this.gdPath = null;
                }
            }
            if (this.gdPath == null) {
                this.gdPath = "C:\\Program Files\\Steam\\steamapps\\common\\Grim Dawn";
                file = new File(this.gdPath);
                if (file.exists()) {
                    dirSteam = "C:\\Program Files\\Steam";
                } else {
                    this.gdPath = null;
                }
            }
            if (this.gdPath == null) {
                this.gdPath = "C:\\GOG Games\\Grim Dawn";
                file = new File(this.gdPath);
                if (!file.exists()) {
                    this.gdPath = null;
                }
            }
            this.savePath = ini.get((Object) "directories", (Object) "save_path");
            if (this.savePath == null) {
                this.savePath = GDConstants.USER_HOME + "\\Documents\\My Games\\Grim Dawn\\save";
                file = new File(this.savePath);
                if (!file.exists()) {
                    this.savePath = null;
                }
            }
            if (this.savePath == null && dirSteam != null) {
                this.savePath = dirSteam + "\\userdata";
                file = new File(this.savePath);
                this.savePath = null;
                if (file.exists()) {
                    final File[] files = file.listFiles();
                    for (int i = 0; i < files.length; ++i) {
                        if (files[i].isDirectory()) {
                            try {
                                file = new File(files[i].getCanonicalPath() + "\\219990\\remote\\save");
                                if (file.exists()) {
                                    this.savePath = file.getCanonicalPath();
                                    break;
                                }
                            } catch (IOException ex) {
                            }
                        }
                    }
                }
            }
            this.exportPath = ini.get((Object) "directories", (Object) "export_path");
        }

        public void putIniValues(final Ini ini) {
            ini.remove((Object) "directories", (Object) "gd_path");
            ini.remove((Object) "directories", (Object) "save_path");
            ini.remove((Object) "directories", (Object) "export_path");
            ini.remove((Object) "directories", (Object) "buffer_type");
            ini.put("directories", "gd_path", (Object) this.gdPath);
            ini.put("directories", "save_path", (Object) this.savePath);
            ini.put("directories", "export_path", (Object) this.exportPath);
        }

        public void remove(final Ini ini) {
            ini.remove((Object) "directories");
        }
    }

    public static class RestrictionSection implements Cloneable {
        private static final String SECTION = "restrictions";
        private static final String KEY_ALLOW_EDIT = "allow_edit";
        private static final String KEY_TRANS_SC_HC = "transfer_sc_hc";
        private static final String KEY_TRANS_SOUL = "transfer_soulbound";
        private static final String KEY_COMPLETION_ALL = "completion_all";
        private static final String KEY_BLACKSMITH_ALL = "blacksmith_all";
        private static final String KEY_AFFIX_COMBI = "affix_combi";
        private static final String KEY_STASH_MOVE = "stash_move";
        public boolean allowEdit;
        public boolean transferSCHC;
        public boolean transferSoulbound;
        public int affixCombi;
        public boolean completionAll;
        public boolean blacksmithAll;
        public boolean dbStashMove;

        public RestrictionSection() {
            this.allowEdit = true;
            this.transferSCHC = false;
            this.transferSoulbound = false;
            this.affixCombi = 1;
            this.completionAll = false;
            this.blacksmithAll = false;
            this.dbStashMove = false;
        }

        public RestrictionSection clone() {
            final RestrictionSection section = new RestrictionSection();
            section.allowEdit = this.allowEdit;
            section.transferSCHC = this.transferSCHC;
            section.transferSoulbound = this.transferSoulbound;
            section.affixCombi = this.affixCombi;
            section.completionAll = this.completionAll;
            section.blacksmithAll = this.blacksmithAll;
            section.dbStashMove = this.dbStashMove;
            return section;
        }

        public void getIniValues(final Ini ini) {
            final String flag = ini.get((Object) "restrictions", (Object) "allow_edit");
            if (flag == null) {
                this.allowEdit = true;
            } else {
                this.allowEdit = Boolean.parseBoolean(flag);
            }
            this.transferSCHC = Boolean.parseBoolean(ini.get((Object) "restrictions", (Object) "transfer_sc_hc"));
            this.transferSoulbound = Boolean.parseBoolean(ini.get((Object) "restrictions", (Object) "transfer_soulbound"));
            this.completionAll = Boolean.parseBoolean(ini.get((Object) "restrictions", (Object) "completion_all"));
            this.blacksmithAll = Boolean.parseBoolean(ini.get((Object) "restrictions", (Object) "blacksmith_all"));
            this.dbStashMove = Boolean.parseBoolean(ini.get((Object) "restrictions", (Object) "stash_move"));
            try {
                this.affixCombi = Integer.parseInt(ini.get((Object) "restrictions", (Object) "affix_combi"));
            } catch (NumberFormatException ex) {
                this.affixCombi = 1;
            }
        }

        public void putIniValues(final Ini ini) {
            ini.remove((Object) "restrictions", (Object) "allow_edit");
            ini.remove((Object) "restrictions", (Object) "transfer_sc_hc");
            ini.remove((Object) "restrictions", (Object) "transfer_soulbound");
            ini.remove((Object) "restrictions", (Object) "affix_combi");
            ini.remove((Object) "restrictions", (Object) "completion_all");
            ini.remove((Object) "restrictions", (Object) "blacksmith_all");
            ini.remove((Object) "restrictions", (Object) "stash_move");
            ini.put("restrictions", "allow_edit", (Object) Boolean.toString(this.allowEdit));
            ini.put("restrictions", "transfer_sc_hc", (Object) Boolean.toString(this.transferSCHC));
            ini.put("restrictions", "transfer_soulbound", (Object) Boolean.toString(this.transferSoulbound));
            ini.put("restrictions", "affix_combi", (Object) Integer.toString(this.affixCombi));
            ini.put("restrictions", "completion_all", (Object) Boolean.toString(this.completionAll));
            ini.put("restrictions", "blacksmith_all", (Object) Boolean.toString(this.blacksmithAll));
            ini.put("restrictions", "stash_move", (Object) Boolean.toString(this.dbStashMove));
        }

        public void remove(final Ini ini) {
            ini.remove((Object) "restrictions");
        }
    }

    public static class UISection implements Cloneable {
        private static final String SECTION = "ui";
        private static final String KEY_LANGUAGE = "language";
        private static final String KEY_LOOK_N_FEEL = "look_feel";
        private static final String KEY_FONT_SIZE = "font_size";
        private static final String KEY_SYS_TRAY = "system_tray";
        private static final String KEY_GRAPHIC_SCALE = "graphic_scale";
        private static final String KEY_STASH_LAST = "stash_last";
        private static final int DEFAULT_FONTSIZE = 12;
        private static final int DEFAULT_GRAPHICSCALE = 100;
        private static final String DEFAULT_LOOK_N_FEEL = "Metal";
        public String language;
        public int fontSize;
        public int graphicScale;
        public String lookNFeel;
        public boolean minimizeToTray;

        public UISection() {
            this.language = "English";
            this.fontSize = 12;
            this.graphicScale = 100;
            this.lookNFeel = "Metal";
            this.minimizeToTray = false;
        }

        public UISection clone() {
            final UISection section = new UISection();
            section.language = this.language;
            section.fontSize = this.fontSize;
            section.graphicScale = this.graphicScale;
            section.lookNFeel = this.lookNFeel;
            section.minimizeToTray = this.minimizeToTray;
            return section;
        }

        public void getIniValues(final Ini ini) {
            this.language = ini.get((Object) "ui", (Object) "language");
            if (this.language == null) {
                this.language = "English";
            }
            this.lookNFeel = ini.get((Object) "ui", (Object) "look_feel");
            if (this.lookNFeel == null) {
                this.lookNFeel = "Metal";
            }
            try {
                this.fontSize = Integer.parseInt(ini.get((Object) "ui", (Object) "font_size"));
            } catch (NumberFormatException ex) {
                this.fontSize = 12;
            }
            try {
                this.graphicScale = Integer.parseInt(ini.get((Object) "ui", (Object) "graphic_scale"));
            } catch (NumberFormatException ex) {
                this.graphicScale = 100;
            }
            try {
                this.minimizeToTray = Boolean.parseBoolean(ini.get((Object) "ui", (Object) "system_tray"));
            } catch (NumberFormatException ex) {
                this.minimizeToTray = false;
            }
        }

        public void putIniValues(final Ini ini) {
            ini.remove((Object) "ui", (Object) "language");
            ini.remove((Object) "ui", (Object) "font_size");
            ini.remove((Object) "ui", (Object) "graphic_scale");
            ini.remove((Object) "ui", (Object) "look_feel");
            ini.remove((Object) "ui", (Object) "system_tray");
            ini.put("ui", "language", (Object) this.language);
            ini.put("ui", "font_size", (Object) Integer.toString(this.fontSize));
            ini.put("ui", "graphic_scale", (Object) Integer.toString(this.graphicScale));
            ini.put("ui", "look_feel", (Object) this.lookNFeel);
            ini.put("ui", "system_tray", (Object) Boolean.toString(this.minimizeToTray));
        }

        public void remove(final Ini ini) {
            ini.remove((Object) "ui");
        }
    }

    public static class HistorySection implements Cloneable {
        private static final String SECTION = "history";
        private static final String KEY_LAST_STASH = "last_stash";
        private static final String KEY_LAST_MOD = "last_mod";
        public String lastStash;
        public String lastMod;

        public HistorySection() {
            this.lastStash = null;
            this.lastMod = null;
        }

        public HistorySection clone() {
            final HistorySection section = new HistorySection();
            section.lastStash = this.lastStash;
            section.lastMod = this.lastMod;
            return section;
        }

        public void getIniValues(final Ini ini) {
            this.lastStash = ini.get((Object) "history", (Object) "last_stash");
            this.lastMod = ini.get((Object) "history", (Object) "last_mod");
        }

        public void putIniValues(final Ini ini) {
            ini.remove((Object) "history", (Object) "last_stash");
            ini.remove((Object) "history", (Object) "last_mod");
            ini.put("history", "last_stash", (Object) this.lastStash);
            ini.put("history", "last_mod", (Object) this.lastMod);
        }

        public void remove(final Ini ini) {
            ini.remove((Object) "history");
        }
    }

    public static class WindowSection implements Cloneable {
        private static final String SECTION = "window";
        private static final String KEY_X_POS = "x_pos";
        private static final String KEY_Y_POS = "y_pos";
        private static final String KEY_HEIGHT = "height";
        private static final String KEY_WIDTH = "width";
        private static final String KEY_MAXIMIZED = "maximized";
        private static final int DEFAULT_HEIGHT = 920;
        private static final int DEFAULT_WIDTH = 1680;
        public int x;
        public int y;
        public int w;
        public int h;
        public boolean maximized;

        public WindowSection() {
            final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            final int scrWidth = (int) screenSize.getWidth();
            final int scrHeight = (int) screenSize.getHeight();
            if (scrWidth < 1680) {
                this.w = scrWidth;
            } else {
                this.w = 1680;
            }
            if (scrHeight < 920) {
                this.h = scrHeight;
            } else {
                this.h = 920;
            }
            this.x = (scrWidth - this.w) / 2;
            if (scrWidth < this.w) {
                this.x = 0;
            }
            this.y = (scrHeight - this.h) / 2;
            if (scrHeight < this.h) {
                this.y = 0;
            }
            this.maximized = false;
        }

        public WindowSection clone() {
            final WindowSection section = new WindowSection();
            section.x = this.x;
            section.y = this.y;
            section.w = this.w;
            section.h = this.h;
            section.maximized = this.maximized;
            return section;
        }

        public void getIniValues(final Ini ini) {
            final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            final int scrWidth = (int) screenSize.getWidth();
            final int scrHeight = (int) screenSize.getHeight();
            this.maximized = Boolean.parseBoolean(ini.get((Object) "window", (Object) "maximized"));
            try {
                this.h = Integer.parseInt(ini.get((Object) "window", (Object) "height"));
                if (this.h < 0) {
                    this.h = 920;
                }
                if (this.h > scrHeight) {
                    this.h = scrHeight;
                }
            } catch (NumberFormatException ex) {
                if (scrHeight < 920) {
                    this.h = scrHeight;
                } else {
                    this.h = 920;
                }
            }
            try {
                this.w = Integer.parseInt(ini.get((Object) "window", (Object) "width"));
                if (this.w < 0) {
                    this.w = 1680;
                }
                if (this.w > scrWidth) {
                    this.w = scrWidth;
                }
            } catch (NumberFormatException ex) {
                if (scrWidth < 1680) {
                    this.w = scrWidth;
                } else {
                    this.w = 1680;
                }
            }
            try {
                this.x = Integer.parseInt(ini.get((Object) "window", (Object) "x_pos"));
                if (this.x < 0) {
                    this.x = 0;
                }
                if (this.x > scrWidth) {
                    this.x = (scrWidth - this.w) / 2;
                    if (this.x < 0) {
                        this.x = 0;
                    }
                }
            } catch (NumberFormatException ex) {
                this.x = (scrWidth - this.w) / 2;
                if (this.x < 0) {
                    this.x = 0;
                }
            }
            try {
                this.y = Integer.parseInt(ini.get((Object) "window", (Object) "y_pos"));
                if (this.y < 0) {
                    this.y = 0;
                }
                if (this.y > scrHeight) {
                    this.y = (scrHeight - this.h) / 2;
                    if (this.y < 0) {
                        this.y = 0;
                    }
                }
            } catch (NumberFormatException ex) {
                this.y = (scrHeight - this.h) / 2;
                if (this.y < 0) {
                    this.y = 0;
                }
            }
        }

        public void putIniValues(final Ini ini) {
            ini.remove((Object) "window", (Object) "x_pos");
            ini.remove((Object) "window", (Object) "y_pos");
            ini.remove((Object) "window", (Object) "width");
            ini.remove((Object) "window", (Object) "height");
            ini.remove((Object) "window", (Object) "maximized");
            ini.put("window", "x_pos", (Object) Integer.toString(this.x));
            ini.put("window", "y_pos", (Object) Integer.toString(this.y));
            ini.put("window", "width", (Object) Integer.toString(this.w));
            ini.put("window", "height", (Object) Integer.toString(this.h));
            ini.put("window", "maximized", (Object) Boolean.toString(this.maximized));
        }

        public void remove(final Ini ini) {
            ini.remove((Object) "window");
        }
    }
}
